package com.ruoyi.system.monitor;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.enums.LevelEnum;
import com.ruoyi.system.domain.MonitorConfig;
import com.ruoyi.system.domain.vo.MonitorDatabaseCountVo;
import com.ruoyi.system.domain.vo.WarnDigestDTO;
import com.ruoyi.system.domain.vo.WarnDigestDetailVo;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.util.Date;
import java.util.List;

@Slf4j
@Component
public class ZabbixService implements MonitorDataService {

    @Override
    public WarnDigestDTO count(MonitorConfig config) {
        JdbcTemplate jdbcTemplate = getJdbcTemplate(config);
        String sql = "select FROM_UNIXTIME(max(clock)) AS lastestTime, count(1) count, severity from problem where r_eventid IS NULL group by severity";
        List<MonitorDatabaseCountVo> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(MonitorDatabaseCountVo.class));
        WarnDigestDTO vo = merge(query, config);
        if (vo.hasCount()) {
            vo.setDetailList(getDetailVoList(null, jdbcTemplate));
        }
        return vo;
    }

    @Override
    public List<WarnDigestDetailVo> detail(MonitorConfig config, LevelEnum type) {
        JdbcTemplate jdbcTemplate = getJdbcTemplate(config);
        return getDetailVoList(type, jdbcTemplate);
    }

    @NotNull
    private List<WarnDigestDetailVo> getDetailVoList(LevelEnum type, JdbcTemplate jdbcTemplate) {
        String sql = String.format("SELECT\n" +
                "  host AS instance,\n" +
                "  FROM_UNIXTIME(clock) AS time,\n" +
                "  name,\n" +
                "  severity AS `level`,\n" +
                "  name AS log\n" +
                "FROM\n" +
                "  `problem`\n" +
                "LEFT JOIN (\n" +
                "    SELECT DISTINCT h.host, f.triggerid\n" +
                "    FROM hosts h,functions f,items i\n" +
                "    WHERE i.itemid=f.itemid\n" +
                "    AND h.hostid=i.hostid\n" +
                ") T ON T.triggerid = problem.objectid\n" +
                "WHERE r_eventid IS NULL \n" +
                " %s \n", getCondition(type));
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WarnDigestDetailVo.class));
    }

    @Override
    public DataSource getDataSource(MonitorConfig config) {
        if (config == null) {
            return null;
        }
//        MonitorParams params = JSON.parseObject(config.getParams(), MonitorParams.class);
//        String dbUrl = "jdbc:mysql://%s:%s/%s?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false";
//        dbUrl = String.format(dbUrl, params.getUrl(), params.getPort(), params.getDbName());
//
//        HikariConfig hikariConfig = new HikariConfig();
//        hikariConfig.setUsername(params.getUsername());
//        hikariConfig.setPassword(params.getPassword());
//        hikariConfig.setJdbcUrl(dbUrl);
//        hikariConfig.setPoolName(config.getName());
//        hikariConfig.setMinimumIdle(1);
//        hikariConfig.setMaximumPoolSize(2);
//        hikariConfig.setMaxLifetime(maxLifetime);
//        hikariConfig.setIdleTimeout(idleTimeout);
//        hikariConfig.setConnectionTestQuery(testQuery);
//        hikariConfig.setDriverClassName(com.mysql.cj.jdbc.Driver.class.getName());
//
//        log.info("【创建数据源】ZABBIX : {}", config.getParams());
//        return new HikariDataSource(hikariConfig);

        SimpleDriverDataSource driverDataSource = new SimpleDriverDataSource();
        String paramStr = config.getParams();
        JSONObject params = JSON.parseObject(paramStr);
        driverDataSource.setDriverClass(com.mysql.cj.jdbc.Driver.class);
        String dbUrl = "jdbc:mysql://%s:%s/%s?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false";
        dbUrl = String.format(dbUrl, params.getString("url"), params.getString("port"), params.getString("dbName"));
        driverDataSource.setUrl(dbUrl);
        //设置用户名和密码
        driverDataSource.setUsername(params.getString("username"));
        driverDataSource.setPassword(params.getString("password"));
        return driverDataSource;
    }

    private String getCondition(LevelEnum type) {
        if (type == null) {
            return "";
        }
        String where = "AND severity IN ";
        if (type == LevelEnum.NORMAL) {
            return where + "(1)";
        } else if (type == LevelEnum.WARNING) {
            return where + "(2, 3)";
        }
        return where + "(4, 5)";
    }

    private static WarnDigestDTO merge(List<MonitorDatabaseCountVo> voList, MonitorConfig config) {
        int normal = 0;
        int warning = 0;
        int critical = 0;
        for (MonitorDatabaseCountVo vo : voList) {
            if (vo.getSeverity() <= 1) {
                normal += vo.getCount();
            } else if (vo.getSeverity() <= 3) {
                warning += vo.getCount();
            } else if (vo.getSeverity() <= 5) {
                critical += vo.getCount();
            }
        }
        Date latestTime = voList.stream().map(MonitorDatabaseCountVo::getLastestTime).max(Date::compareTo).orElse(null);
        JSONObject serverParams = JSON.parseObject(config.getHostParams());
        return new WarnDigestDTO()
                .setConfigId(config.getId())
                .setConfigType(config.getType())
                .setSort(config.getSort())
                .setName(config.getName())
                .setNormal(normal)
                .setWarning(warning)
                .setCritical(critical)
                .setLastestTime(latestTime)
                .setHref(serverParams.getString("url"));
    }

}
